#pragma once

/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author zhouyan
 * @brief iec101规约asdu数据块
*/
#include "xtTypes.h"
#include "IEC_def.h"
#include <vector>
#include <list>

namespace XIEC {
#pragma  pack (push,1)
    struct DataUnitTag{
        xuint8 typeId;
        VSQ vsq;
        union {
            xuint8  cot8[2];
            xuint16 cot16;
        };
        union {
            xuint8  ca8[2];
            xuint16 ca16;
        };
    };
    union InfoObjectAddr {
        xuint8 addr[4];
        xuint32 d;
        InfoObjectAddr() : d(0) {}
    };
    class CInfoObject {
    public:
        CInfoObject() {m_addr.d = 0;}
        virtual ~CInfoObject();
        virtual xuint8* data() = 0;
        virtual xuint8 length() = 0;

        InfoObjectAddr& addr() {return m_addr;}
        const InfoObjectAddr& const_addr() {return m_addr;}
        const xuint8* const_data() {return data();}

    protected:
        InfoObjectAddr m_addr;
    };
    class CVectInfoObject : public std::vector<CInfoObject*> {
    public:
        CVectInfoObject() {}
        ~CVectInfoObject() { clear(); }
        void clear() {
            for(iterator it = begin(); it != end(); it++) {
                if (*it != 0)
                    delete *it;
            }
            std::vector<CInfoObject*>::clear();
        }
    protected:
        CVectInfoObject(CVectInfoObject&);
        void operator=(CVectInfoObject&);
    };
    template<class V>
    class CInfoObjectV : public CInfoObject {
    public:
        virtual xuint8* data() { return reinterpret_cast<xuint8*>(&value_); }
        virtual xuint8 length() {return sizeof(CInfoObjectV)-sizeof(CInfoObject);}
        V* value() {return &value_;}
    protected:
        V value_;
    };
    template<class T>
    class CInfoObjectT : public CInfoObject {
    public:
        virtual xuint8* data() { return reinterpret_cast<xuint8*>(&tm_); }
        virtual xuint8 length() {return sizeof(CInfoObjectT)-sizeof(CInfoObject);}
        T* time() {return &tm_;}
    protected:
        T tm_;
    };
    template<class V, class Q>
    class CInfoObjectVQ : public CInfoObjectV<V> {
    public:
        virtual xuint8 length() {return sizeof(CInfoObjectVQ)-sizeof(CInfoObject);}
        Q* qs() { return &qs_; }
    protected:
        Q qs_;
    };
    template<class V, class T>
    class CInfoObjectVT : public CInfoObjectV<V> {
    public:
        virtual xuint8 length() {return sizeof(CInfoObjectVT)-sizeof(CInfoObject);}
        T* tm() { return &tm_; }
    protected:
        T tm_;
    };
    template<class V, class Q, class T>
    class CInfoObjectVQT : public CInfoObjectVQ<V, Q> {
    public:
        virtual xuint8 length() {return sizeof(CInfoObjectVQT)-sizeof(CInfoObject);}
        T* tm() { return &tm_; }
    protected:
        T tm_;
    };
    typedef CInfoObjectV<SIQ> CInfoObject_SIQ;
    typedef CInfoObjectVT<SIQ, CP24Time2a> CInfoObject_SIQ_TM24;
    typedef CInfoObjectVT<SIQ, CP56Time2a> CInfoObject_SIQ_TM56;
    typedef CInfoObjectV<DIQ> CInfoObject_DIQ;
    typedef CInfoObjectVT<DIQ, CP24Time2a> CInfoObject_DIQ_TM24;
    typedef CInfoObjectVT<DIQ, CP56Time2a> CInfoObject_DIQ_TM56;
    typedef CInfoObjectV<VTI> CInfoObject_VTI;
    typedef CInfoObjectVQ<VTI, QDS> CInfoObject_VTI_QDS;
    typedef CInfoObjectVQT<VTI, QDS, CP24Time2a> CInfoObject_VTI_QDS_TM24;
    typedef CInfoObjectVQT<VTI, QDS, CP56Time2a> CInfoObject_VTI_QDS_TM56;
    typedef CInfoObjectV<BitString> CInfoObject_BitString;
    typedef CInfoObjectVQ<BitString, QDS> CInfoObject_BitString_QDS;
    typedef CInfoObjectVQT<BitString, QDS, CP24Time2a> CInfoObject_BitString_QDS_TM24;
    typedef CInfoObjectVQT<BitString, QDS, CP56Time2a> CInfoObject_BitString_QDS_TM56;
    typedef CInfoObjectV<shortFloat> CInfoObject_FLOAT;
    typedef CInfoObjectVQ<shortFloat, QDS> CInfoObject_FLOAT_QDS;
    typedef CInfoObjectVQT<shortFloat, QDS, CP24Time2a> CInfoObject_FLOAT_QDS_TM24;
    typedef CInfoObjectVQT<shortFloat, QDS, CP56Time2a> CInfoObject_FLOAT_QDS_TM56;
    typedef CInfoObjectV<NVA> CInfoObject_NVA;
    typedef CInfoObjectVQ<NVA, QDS> CInfoObject_NVA_QDS;
    typedef CInfoObjectVQT<NVA, QDS, CP24Time2a> CInfoObject_NVA_QDS_TM24;
    typedef CInfoObjectVQT<NVA, QDS, CP56Time2a> CInfoObject_NVA_QDS_TM56;
    typedef CInfoObjectV<SVA> CInfoObject_SVA;
    typedef CInfoObjectVQ<SVA, QDS> CInfoObject_SVA_QDS;
    typedef CInfoObjectVQT<SVA, QDS, CP24Time2a> CInfoObject_SVA_QDS_TM24;
    typedef CInfoObjectVQT<SVA, QDS, CP56Time2a> CInfoObject_SVA_QDS_TM56;
    typedef CInfoObjectV<BCR> CInfoObject_BCR;
    typedef CInfoObjectVT<BCR, CP24Time2a> CInfoObject_BCR_TM24;
    typedef CInfoObjectVT<BCR, CP56Time2a> CInfoObject_BCR_TM56;
    typedef CInfoObjectVQ<SCD, QDS> CInfoObject_SCD_QDS;
    typedef CInfoObjectV<COI> CInfoObject_COI;
    typedef CInfoObjectVQ<shortFloat, QOS> CInfoObject_FLOAT_QOS;
    typedef CInfoObjectVQ<NVA, QOS> CInfoObject_NVA_QOS;
    typedef CInfoObjectVQ<SVA, QOS> CInfoObject_SVA_QOS;
    typedef CInfoObjectVQ<BitString, QOS> CInfoObject_BitString_QOS;
    typedef CInfoObjectVQ<shortFloat, QPM> CInfoObject_FLOAT_QPM;
    typedef CInfoObjectVQ<SVA, QPM> CInfoObject_SVA_QPM;
    typedef CInfoObjectVQ<NVA, QPM> CInfoObject_NVA_QPM;
    typedef CInfoObject_SIQ CInfoObject1;
    typedef CInfoObject_SIQ_TM24 CInfoObject2;
    typedef CInfoObject_DIQ CInfoObject3;
    typedef CInfoObject_DIQ_TM24 CInfoObject4;
    typedef CInfoObject_VTI_QDS CInfoObject5;
    typedef CInfoObject_VTI_QDS_TM24 CInfoObject6;
    typedef CInfoObject_BitString_QDS CInfoObject7;
    typedef CInfoObject_BitString_QDS_TM24 CInfoObject8;
    typedef CInfoObject_NVA_QDS  CInfoObject9;
    typedef CInfoObject_NVA_QDS_TM24  CInfoObject10;
    typedef CInfoObject_SVA_QDS CInfoObject11;
    typedef CInfoObject_SVA_QDS_TM24 CInfoObject12;
    typedef CInfoObject_FLOAT_QDS CInfoObject13;
    typedef CInfoObject_FLOAT_QDS_TM24 CInfoObject14;
    typedef CInfoObject_BCR CInfoObject15;
    typedef CInfoObject_BCR_TM24 CInfoObject16;
    class CInfoObject17 : public CInfoObject {
    public:
        virtual xuint8* data() {return reinterpret_cast<xuint8*>(&m_data);}
        virtual xuint8 length() {return sizeof(m_data);}
        SEP& sep() {return m_data.sep;}
        CP16Time2a& time16() {return m_data.tm16;}
        CP24Time2a& time24() {return m_data.tm24;}
    private:
        struct {
            SEP sep;
            CP16Time2a tm16;
            CP24Time2a tm24;
        }m_data;
    };
    class CInfoObject18 : public CInfoObject {
    public:
        virtual xuint8* data() {return reinterpret_cast<xuint8*>(&m_data);}
        virtual xuint8 length() {return sizeof(m_data);}
        SPE& spe() {return m_data.spe;}
        QDP& qdp() {return m_data.qdp;}
        CP16Time2a& time16() {return m_data.tm16;}
        CP24Time2a& time24() {return m_data.tm24;}
    private:
        struct {
            SPE spe;
            QDP qdp;
            CP16Time2a tm16;
            CP24Time2a tm24;
        }m_data;
    };
    class CInfoObject19 : public CInfoObject {
    public:
        virtual xuint8* data() {return reinterpret_cast<xuint8*>(&m_data);}
        virtual xuint8 length() {return sizeof(m_data);}
        OCI& oci() {return m_data.oci;}
        QDP& qdp() {return m_data.qdp;}
        CP16Time2a& time16() {return m_data.tm16;}
        CP24Time2a& time24() {return m_data.tm24;}
    private:
        struct {
            OCI oci;
            QDP qdp;
            CP16Time2a tm16;
            CP24Time2a tm24;
        }m_data;
    };
    typedef CInfoObject_SCD_QDS CInfoObject20;
    typedef CInfoObject_NVA  CInfoObject21;
    typedef CInfoObject_SIQ_TM56 CInfoObject30;
    typedef CInfoObject_DIQ_TM56 CInfoObject31;
    typedef CInfoObject_VTI_QDS_TM56 CInfoObject32;
    typedef CInfoObject_BitString_QDS_TM56 CInfoObject33;
    typedef CInfoObject_NVA_QDS_TM56  CInfoObject34;
    typedef CInfoObject_SVA_QDS_TM56 CInfoObject35;
    typedef CInfoObject_FLOAT_QDS_TM56 CInfoObject36;
    typedef CInfoObject_BCR_TM56 CInfoObject37;
    class CInfoObject38 : public CInfoObject {
    public:
        virtual xuint8* data() {return reinterpret_cast<xuint8*>(&m_data);}
        virtual xuint8 length() {return sizeof(m_data);}
        SEP& sep() {return m_data.sep;}
        CP16Time2a& time16() {return m_data.tm16;}
        CP56Time2a& time56() {return m_data.tm56;}
    private:
        struct {
            SEP sep;
            CP16Time2a tm16;
            CP56Time2a tm56;
        }m_data;
    };
    class CInfoObject39 : public CInfoObject {
    public:
        virtual xuint8* data() {return reinterpret_cast<xuint8*>(&m_data);}
        virtual xuint8 length() {return sizeof(m_data);}
        SEP& sep() {return m_data.sep;}
        QDP& qdp() {return m_data.qdp;}
        CP16Time2a& time16() {return m_data.tm16;}
        CP56Time2a& time56() {return m_data.tm56;}
    private:
        struct {
            SEP sep;
            QDP qdp;
            CP16Time2a tm16;
            CP56Time2a tm56;
        }m_data;
    };
    class CInfoObject40 : public CInfoObject {
    public:
        virtual xuint8* data() {return reinterpret_cast<xuint8*>(&m_data);}
        virtual xuint8 length() {return sizeof(m_data);}
        OCI& oci() {return m_data.oci;}
        QDP& qdp() {return m_data.qdp;}
        CP16Time2a& time16() {return m_data.tm16;}
        CP56Time2a& time56() {return m_data.tm56;}
    private:
        struct {
            OCI oci;
            QDP qdp;
            CP16Time2a tm16;
            CP56Time2a tm56;
        }m_data;
    };
    typedef CInfoObjectV<SCO> CInfoObject45;
    typedef CInfoObjectV<DCO> CInfoObject46;
    typedef CInfoObjectV<RCO> CInfoObject47;
    typedef CInfoObject_NVA_QOS CInfoObject48;
    typedef CInfoObject_SVA_QOS CInfoObject49;
    typedef CInfoObject_FLOAT_QOS CInfoObject50;
    typedef CInfoObject_BitString_QOS CInfoObject51;
    typedef CInfoObjectV<COI> CInfoObject70;
    class CInfoObject100 : public CInfoObjectV<QOI> {
    public:
        CInfoObject100(xuint8 qoi=20);
    };
    typedef CInfoObjectV<QCC> CInfoObject101;
    class CInfoObject102 : public CInfoObject {
    public:
        virtual xuint8* data() {return reinterpret_cast<xuint8*>(0);}
        virtual xuint8 length() {return 0;}
    };
    typedef CInfoObjectT<CP56Time2a> CInfoObject103;
    typedef CInfoObjectV<FBP> CInfoObject104;
    typedef CInfoObjectV<QRP> CInfoObject105;
    typedef CInfoObjectT<CP16Time2a> CInfoObject106;
    typedef CInfoObject_NVA_QPM CInfoObject110;
    typedef CInfoObject_SVA_QPM CInfoObject111;
    typedef  CInfoObject_FLOAT_QPM CInfoObject112;
    typedef CInfoObjectV<QPA> CInfoObject113;
#pragma pack(pop)
};
